[AWS CDK] Step Functions の EcsRunTask でタスクサイズをオーバーライド可能になりました

[AWS CDK] Step Functions の EcsRunTask でタスクサイズをオーバーライド可能になりました

Clock Icon2024.09.03

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最近のリリースで、下記のアップデートが追加されていました。

https://github.com/aws/aws-cdk/releases/tag/v2.155.0

stepfunctions-tasks: add cpu and memory parameters to EcsRunTask (#30140) (986e378), closes #30027

Amazon ECS のタスク定義では、パラメーターとしてタスクサイズを設定でき、タスク実行時の最大 CPU およびメモリーのサイズを指定できます。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html

今回の AWS CDK のアップデートは、AWS Step Functions の EcsRunTask でタスクサイズのオーバーライドが設定可能になったというものです。

試してみた

オーバーライドを指定しない場合

まず、EcsRunTask でのタスクサイズのオーバーライドを指定しない場合を試してみます。

CDK の実装で、タスクサイズを、cpu が 256 (.25 vCPU)、メモリーが 512 (0.5 GB) としたタスク定義の ECS タスクをステートマシンで実行するようにします。

lib/cdk-sample-stack.ts
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // VPCの作成
    const vpc = new ec2.Vpc(this, 'MyVpc');

    // ECSクラスターの作成
    const cluster = new ecs.Cluster(this, 'MyCluster', {
      vpc,
    });

    // タスク定義の作成
    const taskDefinition = new ecs.FargateTaskDefinition(
      this,
      'TaskDefinition',
      {
        cpu: 256,
        memoryLimitMiB: 512,
        runtimePlatform: {
          cpuArchitecture: ecs.CpuArchitecture.ARM64,
        },
      }
    );

    // コンテナの追加
    taskDefinition.addContainer('Container', {
      image: ecs.ContainerImage.fromAsset('./nodejs-app'),
      portMappings: [{ containerPort: 3000 }],
    });

    // ECSタスクの実行
    const runTask = new tasks.EcsRunTask(this, 'RunTask', {
      integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE,
      cluster,
      taskDefinition,
      launchTarget: new tasks.EcsFargateLaunchTarget()
    });

    // ステートマシンの作成
    new sfn.StateMachine(this, 'StateMachine', {
      definitionBody: sfn.DefinitionBody.fromChainable(runTask),
    });
  }
}

上記を CDK デプロイし、作成されたタスク定義を確認するとサイズが指定通りになっていることが確認できます。

ステートマシンを開始すると、実行が成功しました。

実行された ECS タスクを確認すると、想定どおり .25 vCPU および 0.5 GB メモリーが使用されています。

CDK モジュールのアップデート

AWS CDK モジュールを v2.155.0 以上にアップデートして、今回のアップデートを利用できるようにします。

npm i aws-cdk-lib@latest aws-cdk@latest

オーバーライドを指定する場合

以下の CDK の実装は、「タスク定義の作成」および「コンテナの追加」までは先ほどと同じですが、EcsRunTask の cpu および memoryMiB にタスク定義より大きい値(cpu を 512 (.5 vCPU)、メモリーを 1024 (1 GB))を指定しています。

lib/cdk-sample-stack.ts
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // VPCの作成
    const vpc = new ec2.Vpc(this, 'MyVpc');

    // ECSクラスターの作成
    const cluster = new ecs.Cluster(this, 'MyCluster', {
      vpc,
    });

    // タスク定義の作成
    const taskDefinition = new ecs.FargateTaskDefinition(
      this,
      'TaskDefinition',
      {
        cpu: 256,
        memoryLimitMiB: 512,
        runtimePlatform: {
          cpuArchitecture: ecs.CpuArchitecture.ARM64,
        },
      }
    );

    // コンテナの追加
    taskDefinition.addContainer('Container', {
      image: ecs.ContainerImage.fromAsset('./nodejs-app'),
      portMappings: [{ containerPort: 3000 }],
    });

    // ECSタスクの実行
    const runTask = new tasks.EcsRunTask(this, 'RunTask', {
      integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE,
      cluster,
      taskDefinition,
      launchTarget: new tasks.EcsFargateLaunchTarget(),
      cpu: '512', // 最大 CPU サイズを上書き
      memoryMiB: '1024', // 最大メモリサイズを上書き
    });

    // ステートマシンの作成
    new sfn.StateMachine(this, 'StateMachine', {
      definitionBody: sfn.DefinitionBody.fromChainable(runTask),
    });
  }
}

CDK Diff を確認すると、EcsRunTask の cpu および memoryMiB が変更されていることが確認できます。

$ npx cdk diff
Stack CdkSampleStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Resources
[~] AWS::StepFunctions::StateMachine StateMachine StateMachine2E01A3A5
 └─ [~] DefinitionString
     └─ [~] .Fn::Join:
         └─ @@ -27,6 +27,6 @@
            [ ]         "GroupId"
            [ ]       ]
            [ ]     },
            [-]     "\"]}},\"LaunchType\":\"FARGATE\"}}}}"
            [+]     "\"]}},\"Overrides\":{\"Cpu\":\"512\",\"Memory\":\"1024\"},\"LaunchType\":\"FARGATE\"}}}}"
            [ ]   ]
            [ ] ]

✨  Number of stacks with differences: 1

上記を CDK デプロイ後に、ステートマシンを開始すると、実行が成功しました。

ECS タスクを確認すると、指定したタスクサイズ(.5 vCPU および 1 GB)で起動されていることが確認できました。

無効な CPU と メモリーサイズでオーバーライドを試みた場合

ドキュメントにある通り、ECS タスクの CPU およびメモリーサイズの組み合わせには制限があります。

無効な CPU とメモリーサイズでオーバーライドを試みてみます。

lib/cdk-sample-stack.ts
    // ECSタスクの実行
    const runTask = new tasks.EcsRunTask(this, 'RunTask', {
      integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE,
      cluster,
      taskDefinition,
      launchTarget: new tasks.EcsFargateLaunchTarget(),
      // 不正な CPU および メモリーの組み合わせを指定
      cpu: '128', // 最大 CPU サイズを上書き
      memoryMiB: '1024', // 最大メモリサイズを上書き
    });

上記の CDK デプロイは成功しますが、ステートマシンの実行が失敗しました。

エラーメッセージによると、ステートマシンのタスク(ECS ではない)の実行が、値の構成が存在しないためエラーとなっています。

No Fargate configuration exists for given values. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: 39a776db-0aa7-4cdb-abe4-c311042480b8; Proxy: null)

このように、無効な組み合わせが指定された場合は、Synth 時や Deploy 時ではなくステートマシンでのタスクの実行時に初めてエラーとなるので注意しましょう。

おわりに

AWS CDK で Step Functions の EcsRunTask でタスクサイズをオーバーライド可能になったのでご紹介しました。

これにより実行させたい処理に応じてタスクサイズを柔軟に設定する運用が簡単に実装可能になったので、活用してみてください。

参考

https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html

以上

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.